#coding=utf-8

require "aio/core"

class Aio::Module::OutputStyle::SummaryReport < Aio::Module::OutputStyle
  include Aio::Module
  include Aio::Device
  include Aio::Base::Toolkit::WordWps
  include Aio::Base::Toolkit::ExcelWps
  include Aio::Ui::Verbose

  PlaceHolder = "###"

  def initialize
    super({
      :author				=> "Elin",
      :description	=> "输出巡检简要报告, 以WPS运行",
      :file_suffix	=> "doc",
      :platform     => ['windows']
    })

    # 附带信息
    @info = {
      :resource_file => File.join(::BaseFile, "aio", "resource"),
      :client		=> nil,
      :time 		=> ::Time.now.to_s.split(' ')[0],
    }
  end

  def info_client=(e)
    @info[:client] = e
  end

  def info_time=(e)
    @info[:time] = e
  end

  def info
    @info
  end


  def generate

    word = Word.new
    #word.show
    word.display_alerts = false
    @doc = word.init_document
    @text = @doc.add_text

    # 创建风格
    create_style

    device_manager.devices.each_pair do |device_name, klass|
      #puts "summary_report"
      #pp device_name
      #pp klass.warning_klass
    end


    # 标号
    @mark	= [0, 0, 0]

    # 按流程算法运行
    process(info)

    # 保存
    word.display_alerts = true

    begin
      word.save(output_file.to_s)
    rescue Exception => e
      e.message
    ensure
      #word.close
    end
  end

  # 创建风格
  def create_style

    # 用于目录的标题
    @doc.create_style_self("Contents") do |sty|
      sty.font.size = 20
      sty.font.NameFarEast = "黑体"
      sty.font.NameAscii = "Book Antiqua"
      sty.font.NameOther = "Book Antiqua"
      sty.font.bold = true
      # 段落间距
      sty.ParagraphFormat.Alignment = 2		# 文本右对齐
      sty.ParagraphFormat.LineUnitBefore = 3	# 
      sty.ParagraphFormat.LineUnitAfter = 2
      sty.NextParagraphStyle = "正文"
      # 段落控制
      sty.ParagraphFormat.WidowControl = true
      sty.ParagraphFormat.KeepWithNext = true
      sty.ParagraphFormat.PageBreakBefore = true
      # 边框
      sty.ParagraphFormat.Borders(-1).LineStyle = 0
      sty.ParagraphFormat.Borders(-2).LineStyle = 0
      sty.ParagraphFormat.Borders(-4).LineStyle = 0
      bottom = sty.ParagraphFormat.Borders(-3)
      bottom.LineStyle = 1
      bottom.LineWidth = 12
      bottom.Color = 0
    end

    # 一级标题
    @doc.create_style_self("font_chapter_name1") do |sty|
      sty.BaseStyle = "Contents"
      sty.ParagraphFormat.OutlineLevel = 1
      sty.NextParagraphStyle = "正文"
    end

    # 一级标题标号
    @doc.create_style_self("font_chapter_num1") do |sty|
      sty.BaseStyle = "Contents"
      sty.font.size = 72
      sty.ParagraphFormat.LineUnitBefore = 0.5
      sty.ParagraphFormat.LineUnitAfter = 0.5
      sty.ParagraphFormat.OutlineLevel = 1
      sty.NextParagraphStyle = "font_chapter_name1"
    end

    # 二级标题
    @doc.create_style_self("font_section_name1") do |sty|
      sty.BaseStyle = "正文"
      sty.font.bold = true
      sty.font.size = 18
      sty.ParagraphFormat.LineUnitBefore = 1
      sty.ParagraphFormat.LineUnitAfter = 1
      sty.ParagraphFormat.OutlineLevel = 2
      sty.NextParagraphStyle = "正文"
    end

    # 二级标题标号
    @doc.create_style_self("font_section_num1") do |sty|
      sty.BaseStyle = "font_section_name1"
      sty.NextParagraphStyle = "font_section_name1"
    end

    @doc.create_style_self("font_level3_name1") do |sty|
      sty.BaseStyle = "正文"
      sty.font.bold = true
      sty.font.size = 18
      sty.ParagraphFormat.LineUnitBefore = 1
      sty.ParagraphFormat.LineUnitAfter = 1
      sty.ParagraphFormat.OutlineLevel = 3
      sty.NextParagraphStyle = "正文"
    end

    @doc.create_style_self("font_level3_num1") do |sty|
      sty.BaseStyle = "font_level3_name1"
      sty.NextParagraphStyle = "font_level3_name1"
    end

    # 要点
    @doc.create_style_self("importance") do |sty|
      sty.BaseStyle = "正文"
      sty.font.bold = true
      sty.font.size = 18
      sty.ParagraphFormat.LineUnitBefore = 1
      sty.ParagraphFormat.LineUnitAfter = 1
      sty.NextParagraphStyle = "正文"
    end
  end

  # 主体流程控制
  def process(info)
    generate_cover(info)
    generate_catalog(info)
    generate_introduction(info)

    generate_summary(info)
    generate_summarize(info)
    update_catalog
  end

  # 创建封面
  def generate_cover(info)
    @text.add_head_image(File.join(info[:resource_file], "cover_picture.png"))
    @text.style = "正文"
    @text.entry
    @text.entry
    @text.entry

    @text.font.size = 16
    @text.center
    @text.section { "数据通信网络高级巡检报告" }
    @text.entry
    @text.entry

    client = info[:client]
    time = info[:time]
    @text.font.Size = 15
    @text.section { "客户名称：#{client}" }
    @text.section { "巡检时间：#{time}" }

    @text.add_table(1,1) { |tbl| }
=begin
    @text.entry
    @text.entry
    @text.entry

    @text.left
    @text.font.bold = true
    @text.add_image(File.join(info[:resource_file], "logo.png"))
=end
  end

  # 生成目录
  def generate_catalog(info)
    @text.section("Contents") { "目  录" }
    @doc.create_catalog
    @text.page_break
  end

  # 生成前言
  def generate_introduction(info)
    @text.section("font_chapter_name1") { "前言" }
    @text.section("font_section_name1") { "概述" }
    @text.puts "根据#{info[:client]}的运行维护需要，公司对其网络设备进行了巡检。本文档提供了本次巡检所有设备的检查明细信息及汇总信息，针对检查中发现的设备在运行过程中存在的故障隐患和风险提出了相关建议，并对网络整体的健康程度进行了评估。"
    @text.entry
    @text.puts "通过本文档，您可以及时了解网络设备的健康状况，清除设备故障隐患，指导技术人员完成对网络的改造优化，提高网络的可用性，保障业务可靠运行。"

    @text.section("font_section_name1") { "读者对象" }
    @text.puts "本项目相关的网络运行维护主管、技术工程师、系统集成商工程师等。"

    @text.page_break
    @text.entry
    @text.section("importance") { "尊敬的_______________________ :" }
    @text.puts "感谢您选择我们的产品和服务！为了提高网络的可用性，保障网络的稳定运行，我们于#{info[:time]}对贵单位网络设备进行了巡检服务。现将本次服务的情况向您汇报如下，并请您对我们的工作给予评价。"
    @text.entry
    @text.puts "感谢您和您的团队在本次服务过程中给我们的配合和支持！"
    @text.entry
    @text.entry
    @text.entry
    @text.entry
    @text.entry
    @text.entry
    @text.entry
    @text.puts "本次巡检负责人："
    @text.puts "联系电话："
    @text.puts "联系邮箱："
  end

  ###
  #
  # 巡检概要报告
  #
  ###
  # 流程控制
  def generate_summary(info)
    add_title_1("巡检概要报告")
    generate_summary_overview(info)
    generate_summary_device_type(info)
    generate_summary_warning_device_top10(info)
    generate_summary_level(info)
    generate_summary_problem(info)
    generate_summary_major_problem(info)
  end

  # 概述
  def generate_summary_overview(info)
    add_title_2("概述")
    tmp = "本次巡检共巡检设备#{device_manager.devices_number}台，" +
      "发现问题#{warning_summarize.total_number}个。" +
      "其中严重问题#{warning_summarize.serious_number}个，" + 
      "一般问题#{warning_summarize.ordinary_number}个。" 
    @text.puts tmp
  end

  # 巡检设备类型
  def generate_summary_device_type(info)
    add_title_2("巡检设备类型")
    @text.puts "下图表示本次巡检各类型设备所占的比例： "

    # 生成table数据目录
    type_info = device_manager.device_type_classify.to_a
    tbl = []
    type_info.size.times do |i|
      # 将Hash 变成数组后,按照indent输出
      tbl << [ type_info[i][0], type_info[i][1].size.to_s ]
    end

    # 生成图表
    @text.chart(tbl) do |chart|
      chart.type = chart.class::Pie
      chart.style = 251
    end
  end

  # 发现问题数TOP20的设备
  def generate_summary_warning_device_top10(info)
    add_title_2("发现问题数TOP10的设备")
    @text.puts "本次巡检发现问题数排名前10的设备，如下图所示： "

    tbl = [["", "serious", "ordinary", "compare"]]

    type_warning_info = warning_summarize.device_warning_sort
    n = 0
    type_warning_info.each do |dev|
      n += 1
      next unless dev[1].total_number > 0
      break if n > 10
      tbl << [	dev[0], 
               dev[1].serious_number,
               dev[1].ordinary_number,
               dev[1].compare_number ]
    end

    @text.chart(tbl) do |chart|
      chart.type = chart.class::ColumnStacked
      chart.style = 251
      chart.series_name = false
      chart.category_name = false
      chart.value = false
      chart.axes_unit(1)
    end
  end

  # 按问题级别展现
  def generate_summary_level(info)

    # 当没有内容的时候，返回
    return if warning_summarize.total_number.zero?

    add_title_2("按问题级别展现")
    @text.puts "本次巡检发现的问题级别分布情况，如下图所示： "
    tbl = []
    if warning_summarize.has_serious?
      tbl << ["serious", warning_summarize.serious_number]
    end

    if warning_summarize.has_ordinary?
      tbl << ["ordinary", warning_summarize.ordinary_number]
    end

    if warning_summarize.has_compare?
      tbl << ["compare", warning_summarize.compare_number]
    end

    @text.chart(tbl) do |chart|
      chart.type = chart.class::Pie
      chart.style = 251
    end

    #------
    @text.entry
    @text.puts "1、本次巡检发现的严重问题数最多的5台设备，如下图所示："
    tbl = warning_summarize.device_serious_sort
    # 只保留5个
    n = 0
    tbl.delete_if { |x| n += 1 ;n > 5 }
    tbl.insert(0, ["", "数量"])
    @text.chart(tbl) do |chart|
      chart.type = chart.class::ColumnClustered
      chart.style = 251
      chart.series_name = false
      chart.category_name = false
      chart.value = false
      chart.axes_unit(1)
    end

    #------
    @text.entry
    @text.puts "2、本次巡检发现的一般问题数最多的5台设备，如下图所示："
    tbl = warning_summarize.device_ordinary_sort
    # 只保留5个
    n = 0
    tbl.delete_if { |x| n += 1 ;n > 5 }
    tbl.insert(0, ["", "数量"])
    @text.chart(tbl) do |chart|
      chart.type = chart.class::ColumnClustered
      chart.style = 251
      chart.series_name = false
      chart.category_name = false
      chart.value = false
      chart.axes_unit(1)
    end
  end

  # 按问题发生频率展现
  def generate_summary_problem(info)
    add_title_2("按问题发生频率展现")
    @text.puts "本次巡检发现的发生频率最多的5类问题，如下图所示："
    tbl = warning_summarize.problem_frequency
    n = 0
    tbl.delete_if { |x| n += 1 ;n > 5 }
    tbl.insert(0, ["", "数量"])
    @text.chart(tbl) do |chart|
      chart.type = chart.class::BarClustered
      chart.style = 251
      chart.series_name = false
      chart.category_name = false
      chart.value = false
      chart.axes_unit(1)
    end
  end

  # 主要问题分析及说明
  def generate_summary_major_problem(info)
    return if warning_summarize.total_number.zero?
    add_title_2("主要问题分析及说明")
    @text.puts "本章节将详细介绍巡检过程中发生的所有严重问题，及发生频率最高的3类一般和提示问题。"

    #------
    warning_summarize.summary[:serious].each_pair do |cs, dev_info|
      desc_klass = warning_summarize.get_desc(cs)
      add_title_3(desc_klass.title)
      level(:serious)
      @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台，明细如下："
      add_device_table(dev_info)
    end

    #------
    warning_summarize.summary[:ordinary].each_pair do |cs, dev_info|
      desc_klass = warning_summarize.get_desc(cs)
      add_title_3(desc_klass.title)
      level(:ordinary)
      @text.puts desc_klass.to_s + "不符合该规则的设备共#{dev_info.size}台，明细如下："
      add_device_table(dev_info)
    end

  end

  # 打印级别
  def level(sym)
    res = ""
    case sym
    when :serious
      res = "级别: 严重"
    when :ordinary
      res = "级别: 一般"
    end

    @text.style = "importance"
    @text.size = 12
    @text.puts res
  end

  # 添加按照设备标明的表格
  def add_device_table(dev_info)
    tbl = [ ["序号",	"名称",	"型号",	"IP"] ]
    n = 1
    dev_info.each_pair do |name, klass_info|
      klass = klass_info[:klass]
      tbl << [n, name, 
              klass.device_info[:device_model],
              klass.get_manager_ip ]
      n += 1
    end
    @text.size = 10
    @text.add_table_by_value(tbl) do |table|
      table.center
      table.border_line
      table.set_columns_width(1, 44)
      table.set_columns_width(2, 143)
      table.set_columns_width(3, 143)
    end
  end


  # 总结流程控制
  def generate_summarize(info)
    @text.page_break
    generate_machine_room(info)
    generate_inspection(info)
    generate_offer(info)
    generate_appraise(info)
  end

  # 机房环境检查结果
  def generate_machine_room(info)
    add_title_2("机房环境检查结果")
    @text.add_table(1,1) do |tbl|
      tbl.height = 100
      tbl.border_line
    end

  end

  # 巡检结论
  def generate_inspection(info)
    add_title_2("巡检结论")
    @text.add_table(1,1) do |tbl|
      tbl.height = 100
      tbl.border_line
    end
  end

  # 运行维护建议
  def generate_offer(info)
    add_title_2("运行维护建议")
    @text.add_table(1,1) do |tbl|
      tbl.height = 100
      tbl.border_line
    end
  end

  # 您对本次巡检情况的评价
  def generate_appraise(info)
    add_title_2("您对本次巡检情况的评价")
    @text.add_table(1,1) do |tbl|
      tbl.height = 100
      tbl.border_line
    end
  end

  private
  ###
  #
  #  本地方法
  #
  ###
  # 更新目录
  def update_catalog
    @doc.update_catalog
  end

  # 1级标题
  def add_title_1(str)
    @mark[0] += 1
    @mark[1] = 0
    @mark[2] = 0
    mk = @mark[0].to_s
    @text.style = "font_chapter_name1"
    @text.print join(mk, str)
    modify_num(mk, "font_chapter_num1")
    @text.entry
  end

  # 2级标题
  def add_title_2(str)
    @mark[1] += 1
    @mark[2] = 0
    mk = [@mark[0], @mark[1]].join(".")
    @text.style = "font_section_name1"
    @text.print join(mk, str)
    modify_num(mk, "font_section_num1")
    @text.entry
  end

  # 3级标题
  def add_title_3(str)
    @mark[2] += 1
    mk = [@mark[0], @mark[1], @mark[2]].join(".")
    @text.style = "font_level3_name1"
    @text.print join(mk, str)
    modify_num(mk, "font_level3_num1")
    @text.entry
  end

  # 合并,以空格分开
  def join(*arg)
    arg.join(" ")
  end

  # 修改标题数字
  def modify_num(num, sty)
    @doc.home_key
    @doc.move_right(num.size, 1)
    @text.now.Style = @doc.doc_work.Styles(sty)
    #@text.now.ParagraphFormat.LineUnitBefore = 0.1
    @doc.end_key
  end

  # 添加占位符
  def add_holder(str)
    PlaceHolder + " " + str
  end

  def replace_holder(str, style)
    @text.replace(PlaceHolder, str.to_s, style)
  end

  # 警告信息汇总类
  def warning_summarize
    device_manager.warning_summarize
  end

end
